<?php
class weebUILibrary
{
    /**
    * Construct
    * Loads the library and its parameters
    **/
    function __construct( $libraryID = null )
    {
        if ( $libraryID == null ) $libraryID = $_GET['library'];

        $config = sqlite_open( "config.db" );

        // @todo refactor to use a Config class
        $res = sqlite_query( $config, "SELECT * FROM general" );
        if ( sqlite_num_rows( $res ) == 1 )
        {
            $gen = sqlite_fetch_array( $res );
            foreach ( sqlite_fetch_array( sqlite_query( $config, "SELECT * FROM library WHERE id='$libraryID'" ), SQLITE_ASSOC ) as $fieldName => $fieldValue )
            {
                $this->properties[$fieldName] = $fieldValue;
            }
        }
        else throw new Exception( "Error fetching library #$libraryID from config" );

        $libraryFile = $gen['path'] . "/library/" . $this->file ;
        if ( file_exists( $libraryFile ) )
            $this->db = sqlite_open( $libraryFile );
        else throw new Exception( "Unable to open SQLite database $libraryFile" );
    }

    /**
    * Getter
    * Returns library informations by config field name
    **/
    public function __get( $property )
    {
        if ( isset( $this->properties[$property] ) )
            return $this->properties[$property];
        else
        {
            throw new Exception( "Unknown property $property" );
        }
    }

    /**
    * Runs an SQL query on the library
    * @return sqlite result
    * @throw Exception if the query failed
    **/
    public function query( $query, $resultType = SQLITE_ASSOC )
    {
        $res = @sqlite_query( $this->db, $query, $resultType, $errorMessage );
        if ( !$errorMessage )
        {
            return $res;
        }

        // @todo Add a customized Exception class
        else throw new Exception( "An error occured executing the query '$query': $errorMessage" );
    }

    /**
    * Runs an update query on the library
    * @param string $query
    * @return void
    **/
    public function updateQuery( $query )
    {
        $this->dropUpdateTrigger();

        $res = sqlite_query( $this->db, $query, $resultType, $errorMessage );
        if ( !$errorMessage )
        {
            return $res;
        }

        // @todo Add a customized Exception class
        else throw new Exception( "An error occured executing the query '$query': $errorMessage" );

        $this->createUpdateTrigger();
    }

    /**
     * Runs an insert query on the library
     * @param string $query
     * @return void
     **/
    public function insertQuery( $query )
    {
        sqlite_query( $this->db, "DROP TRIGGER item_dates_insert" );

        $res = sqlite_query( $this->db, $query, $resultType, $errorMessage );
        if ( !$errorMessage )
        {
            return $res;
        }

        // @todo Add a customized Exception class
        else throw new Exception( "An error occured executing the query '$query': $errorMessage" );

        $create_trigger = "CREATE TRIGGER item_dates_insert AFTER INSERT ON items
                           BEGIN
                               INSERT OR REPLACE INTO item_dates ( item_id , created , modified )
                                   VALUES ( new.item_id , idt_now() , idt_now() );
                               UPDATE parameters set param_value = param_value + 1
                                   WHERE param_name = 'data-version';
                           END;";

        sqlite_query( $this->db, $create_trigger );
    }

    /**
    * Returns the library tags
    * @param array $supportedTags. If not given, all the tags are returned
    * @return array tag_<tag_name> => tag_col
    **/
    function tags()
    {
        static $tags = null;

        if ( $tags === null )
        {
            $res = $this->query( "SELECT * FROM tags WHERE tag_name != ''" );

            while ( $row = sqlite_fetch_array( $res ) )
            {
                $tags[ 'tag_' . $row['tag_name'] ] = $row['tag_col'];
            }
        }

        return $tags;
    }

    /**
    * Drops the update trigger from the library*
    **/
    private function dropUpdateTrigger()
    {
        $checkTriggerQuery = "SELECT COUNT(*) FROM sqlite_master WHERE type = 'trigger' AND name = 'item_dates_update'";
        if ( sqlite_fetch_single( sqlite_query( $this->db, $checkTriggerQuery, $resultType = SQLITE_ASSOC ) ) == 1 )
            sqlite_query( $this->db, "DROP TRIGGER item_dates_update" );
    }

    /**
     * Creates the update trigger in the library
     **/
    private function createUpdateTrigger()
    {
        $create_trigger = "CREATE TRIGGER item_dates_update AFTER UPDATE ON items
                           BEGIN
                               UPDATE parameters SET param_value = param_value + 1
                                   WHERE param_name = \"data-version\";
                           END";

        sqlite_query( $this->db, $create_trigger );
    }

    private $properties;

    /**
    * @var sqlite_resource
    **/
    private $db;
}
?>